package com.yswy.app.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.util.Md5Utils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yswy.app.dto.TgCallBackIdReids;
import com.yswy.app.dto.domianVo.PackageManageVo;
import com.yswy.app.service.AppUserService;
import com.yswy.app.service.SysConfigService;
import com.yswy.app.service.TgCallBackIdService;
import com.yswy.app.service.TgChannleService;
import com.yswy.common.runnableUtil.Pooled;
import com.yswy.common.utils.HttpUtil;
import com.yswy.common.utils.StringUtils;
import com.yswy.common.utils.redis.RedisConstants;
import com.yswy.common.utils.redis.RedisUtil;
import com.yswy.domain.common.BasePojo;
import com.yswy.domain.entity.*;
import com.yswy.domain.mapper.TgBindCsjAdMapper;
import com.yswy.domain.mapper.TgCallBackIdMapper;
import com.yswy.domain.mapper.TgChannleChildMapper;
import com.yswy.domain.vo.dto.TgDevice;
import com.yswy.theater.entity.TheaterPlay;
import com.yswy.theater.service.TheaterPlayService;
import com.yswy.theater.vo.res.TheaterPlayResVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
public class TgCallBackIdServiceImpl extends ServiceImpl<TgCallBackIdMapper, TgCallBackId>
        implements TgCallBackIdService {
    @Autowired
    private RedisUtil redisUtil ;
    @Autowired
    private TgChannleService tgChannleService ;
    @Autowired
    private SysConfigService sysConfigService ;
    @Autowired
    private AppUserService appUserService ;

    @Autowired
    private TgChannleChildMapper tgChannleChildMapper ;
    @Autowired
    private TgBindCsjAdMapper tgBindCsjAdMapper ;
    @Autowired
    private TheaterPlayService theaterPlayService ;
    @Override
    @Pooled(executor = "tgCallBackIdInp", poolOverAct = Pooled.PoolOverAct.NEW_THREAD)
    public void addTgCallBackId(Map<String ,String> map , String ip) {
//        long begin = System.currentTimeMillis();
        log.info(JSONObject.toJSONString(map));
        log.info(ip);
        String clickid = map.get("clickid");
        String channle = map.get("channle");
        if (StringUtils.isEmpty(clickid))return;
        if (StringUtils.isEmpty(channle))return;
        TgCallBackConf tgCallBackConf = tgChannleService.getTgCallBackConf(channle);
        if (tgCallBackConf == null){
            log.info("巨量渠道"+channle+"未配置参数");
            return;
        }
        //回传类型  0 付费  1 广告ecpm
        Integer isCallbackType =tgCallBackConf.getCallbackType();
        //登录缓存时间（用于登录回传失效时间）
        Integer isCallbackLoginCacheTime =tgCallBackConf.getLoginCacheTime();
        TgCallBackId tgCallBackId = new TgCallBackId(map, isCallbackType , null , ip);
        String IpMd5 = Md5Utils.getMD5(tgCallBackId.getChannelIp() , "utf8");
        String IpMd5RES = RedisConstants.tgBackLoginLog+IpMd5;
        String callbackparamCrc = RedisConstants.tgBackLoginLog+tgCallBackId.getCallbackparamCrc();
        if (!redisUtil.hasKey(callbackparamCrc)){
            Integer count = count(new LambdaQueryWrapper<TgCallBackId>()
                    .eq(TgCallBackId::getCallbackparamCrc ,tgCallBackId.getCallbackparamCrc()));
            if (count<=0){
                save(tgCallBackId);
                redisUtil.setForObjectTimeCustom(callbackparamCrc, tgCallBackId, 5, TimeUnit.MINUTES);
                if (StringUtils.isNotEmpty(tgCallBackId.getChannelIp())){
                    redisUtil.setForObjectTimeCustom(IpMd5RES, tgCallBackId, isCallbackLoginCacheTime, TimeUnit.HOURS);
                }
            }
        }
//        long end = System.currentTimeMillis();
//        System.out.println("耗时：tg/handleCallback："+ (end-begin));
    }

    @Override
    public TgCallBackIdReids getTgCallBackId(Long userId , String ip ,String key) {
        TgCallBackId tgCallBackId = null ;
        String modelIpMd5 = Md5Utils.getMD5(ip.replaceAll("\\s" , "") , "utf8");
        String modelIpMd5RES = key+modelIpMd5;
        TgCallBackIdReids tgCallBackIdReids = new TgCallBackIdReids();
        if (redisUtil.hasKey(modelIpMd5RES)){
            tgCallBackId = (TgCallBackId)redisUtil.getObejct(modelIpMd5RES);
            tgCallBackIdReids = new TgCallBackIdReids(tgCallBackId  , modelIpMd5  );
        }
        redisUtil.delete(modelIpMd5RES);
        return tgCallBackIdReids;
    }


    @Override
    public String callBackLogin(Long userId , String ip) {
        TgCallBackIdReids tgCallBackIdReids = getTgCallBackId(userId, ip , RedisConstants.tgBackLoginLog) ;
        TgCallBackId tgCallBackId = tgCallBackIdReids.getTgCallBackId() ;
        String modelIpMd5 =tgCallBackIdReids.getModelIpMd5();
        if (tgCallBackId != null){
            TgCallBackConf tgCallBackConf = tgChannleService.getTgCallBackConf(tgCallBackId.getChannle());
            if (tgCallBackConf == null){
                log.info("巨量渠道"+tgCallBackId.getChannle()+"未配置参数");
                return null;
            }
            //缓存时间（用于关键事件回传失效时间）
            Integer isCallbackEventCacheTime =tgCallBackConf.getEventCacheTime();
            //回传登录Key  active
            String loginKey =tgCallBackConf.getLoginKey();
            //是否回传关键事件
            Integer isCallBackEvent =tgCallBackConf.getIsCallBackEvent();
            tgCallBackId.setUserId(userId);
            //回传
            if (tgCallBackId.getIsCallbackType()==1){//广告回传
                Boolean isDeduction = tgChannleService.isDeduction(tgCallBackId.getChannle() , null);
                if (isDeduction){
                    //不回传
                    tgCallBackId.setIsCallbackLogin(2);
                }else {
                    tgCallBackId.setIsCallbackLogin(1);
                    //回传
                    callBack(tgCallBackId ,loginKey );
                    if (isCallBackEvent == 1){
                        redisUtil.setForObjectTimeCustom(RedisConstants.tgBackAdLog+userId, tgCallBackId, isCallbackEventCacheTime, TimeUnit.HOURS);
                    }
                }
            }else {//签约付费回传
                tgCallBackId.setIsCallbackLogin(1);
                //回传
                callBack(tgCallBackId ,loginKey );
                if (isCallBackEvent == 1){
                    redisUtil.setForObjectTimeCustom(RedisConstants.tgBackPayLog+modelIpMd5, tgCallBackId, isCallbackEventCacheTime, TimeUnit.HOURS);
                }
            }
            updateById(tgCallBackId);
            return tgCallBackId.getChannle();
        }else {
            log.info("巨量渠道用户登录未匹配上：userID：" +userId);
            return null ;
        }
    }

    @Override
    public String callBackPay(Long userId , String ip , Integer price) {
        TgCallBackIdReids tgCallBackIdReids = getTgCallBackId(userId, ip , RedisConstants.tgBackPayLog) ;
        TgCallBackId tgCallBackId = tgCallBackIdReids.getTgCallBackId() ;
        if (tgCallBackId != null){
            TgCallBackConf tgCallBackConf = tgChannleService.getTgCallBackConf(tgCallBackId.getChannle());
            if (tgCallBackConf == null){
                log.info("巨量渠道"+tgCallBackId.getChannle()+"未配置参数");
                return null;
            }
            //回传关键事件Key game_addiction
            String eventKey =tgCallBackConf.getEventKey();
            tgCallBackId.setUserId(userId);
            Boolean isDeduction = tgChannleService.isDeduction(tgCallBackId.getChannle() , price);
            if (isDeduction){
                //不回传
                tgCallBackId.setIsCallbackPay(2);
            }else {
                //回传
                callBack(tgCallBackId ,eventKey);
                tgCallBackId.setIsCallbackPay(1);
            }

            updateById(tgCallBackId);
            return tgCallBackId.getChannle();
        }else {
            return null ;
        }
    }

    @Override
    public TheaterPlayResVo getActiveTypeByUserID(Long userId) {

        TheaterPlayResVo theaterPlayResVo =null;
        String key = RedisConstants.TgTheaterPlay+userId ;
        if (redisUtil.hasKey(key)){
            theaterPlayResVo = (TheaterPlayResVo)redisUtil.getObejct(key);
        }else {
            TgCallBackId tgCallBackId = getOne(new LambdaQueryWrapper<TgCallBackId>()
                    .eq(TgCallBackId::getUserId , userId));
            if (tgCallBackId != null){
                TheaterPlay theaterPlay = theaterPlayService.getById(tgCallBackId.getActiveType());
                if (theaterPlay != null){
                    theaterPlayResVo = new TheaterPlayResVo( theaterPlay , false , 1);
                }
            }

        }
        if (theaterPlayResVo!= null){
            redisUtil.setForObjectTimeCustom(key, theaterPlayResVo, 30, TimeUnit.DAYS);
            return  theaterPlayResVo;
        }else {
            return null ;
        }


//        TgCallBackId tgCallBackId = getOne(new LambdaQueryWrapper<TgCallBackId>()
//                .eq(TgCallBackId::getUserId , userId));
//
//        if (tgCallBackId != null){
//            TheaterPlay theaterPlay = theaterPlayService.getById(tgCallBackId.getActiveType());
//            if (theaterPlay != null){
//                TheaterPlayResVo t = new TheaterPlayResVo( theaterPlay);
//                return t;
//            }
//        }
    }


    public static void callBack(TgCallBackId tgCallBackId , String eventEype){
        JSONObject ad = new JSONObject();
        ad.put("callback" ,tgCallBackId.getCallbackparam());
        JSONObject context = new JSONObject();
        context.put("ad", ad);
        JSONObject map = new JSONObject();
        map.put("event_type" , eventEype) ;
        map.put("context" , context) ;
        map.put("timestamp" , new Date().getTime()) ;
        String body = HttpUtil.doPost("https://analytics.oceanengine.com/api/v2/conversion"
                , map);
        log.info("巨量引擎联调 , 响应："+body + " callback: "+tgCallBackId.getCallbackparamCrc()+ " eventEype: "+eventEype);
    }

    public static void main(String[] args) {
//        TgCallBackId tgCallBackId = new TgCallBackId();
//        tgCallBackId.setCallbackparam("B.DGUxYHChX0vKpyJ4HN9xDBV5C9Dk6QdBm2rR27WrkqZwqNvazpKe8r1YRQkkfP67m69b8QVBgmJKjv7MLzdjh1VqSzB9G5aQnnvtzczAn37q1uqkidBTfwlqRYc94beN366lKy7SZG0dMJqyO7oddq");
//
//        callBack(tgCallBackId , "game_addiction");
        String b = "ELS-AN00118.113.4.235";
        String s = "ELS-AN00118.113.4.235";
        System.out.println(b.replaceAll("\\s" , ""));
        System.out.println(s.replaceAll("\\s" , ""));
        System.out.println(Md5Utils.getMD5(b.replaceAll("\\s" , ""), "utf8"));
        System.out.println(Md5Utils.getMD5(s.replaceAll("\\s" , ""), "utf8"));

    }
}

